package org.xi.sims.service.impl;

import cn.hutool.core.bean.BeanUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.stereotype.Service;
import org.xi.sims.base.service.impl.IBaseServiceImpl;
import org.xi.sims.config.exception.CloudException;
import org.xi.sims.pojo.entity.Room;
import org.xi.sims.pojo.form.RoomForm;
import org.xi.sims.pojo.form.SearchRoomForm;
import org.xi.sims.pojo.vo.RoomVO;
import org.xi.sims.pojo.vo.SelectVO;
import org.xi.sims.pojo.vo.TimetableVO;
import org.xi.sims.repository.RoomRepository;
import org.xi.sims.service.RoomService;
import org.xi.sims.service.TimetableService;
import org.xi.sims.util.XinUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author ：xi
 * @time ：Created in 19:10
 * @description：
 */
@Service
public class RoomServiceImpl extends IBaseServiceImpl<Room, RoomRepository> implements RoomService {

    @Autowired
    @Lazy
    private TimetableService timetableService;

    @Override
    public List<SelectVO> select() {
        return new ArrayList<SelectVO>() {{
            repository.findAll().forEach( one -> {
                this.add(SelectVO.builder().label(one.getNumber()).value(one.getId()).build());
            });
        }};
    }

    @Override
    public List<RoomVO> query(SearchRoomForm form) {
        Room room = Room.builder().build();
        BeanUtil.copyProperties(form, room);
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("level", ExampleMatcher.GenericPropertyMatchers.contains())
                .withMatcher("room" ,ExampleMatcher.GenericPropertyMatchers.contains())
                .withMatcher("number" ,ExampleMatcher.GenericPropertyMatchers.contains());
        Example<Room> example = Example.of(room, matcher);

        return vos(repository.findAll(example));
    }

    @Override
    public RoomVO vo(Room room) {
        RoomVO vo = BeanUtil.copyProperties(room, RoomVO.class);
        return vo;
    }

    @Override
    public List<RoomVO> vos(List<Room> rooms) {
        return new ArrayList<RoomVO>(){{
            rooms.forEach( room -> {
                this.add(vo(room));
            });
        }};
    }

    @Override
    public RoomVO saveOrUpdate(RoomForm form) {
        Room room = repository.findByNumber(form.getNumber());

        if (XinUtil.isNull(form.getId())) {
            if (XinUtil.noNull(room)) {
                throw new CloudException("教室号：" + form.getNumber() + " 已存在!");
            }
            room = BeanUtil.copyProperties(form, Room.class);
            return vo(repository.save(room));
        }
        if (XinUtil.noNull(room)) {
            if (!Objects.equals(room.getId(), form.getId())) {
                throw new CloudException("教室号：" + form.getNumber() + " 已存在!");
            }
            BeanUtil.copyProperties(form, room);
        } else {
            room = BeanUtil.copyProperties(form, Room.class);
        }
        return vo(repository.save(room));
    }

    @Override
    public void deleteRoom(Integer id) {
        List<TimetableVO> timetables = timetableService.findVosByRoomId(id);
        if (XinUtil.noNull(timetables)) {
            throw new CloudException("该教室已有班级课程安排，请勿删除!");
        }
        repository.deleteById(id);
    }

    @Override
    public RoomVO findVoById(Integer id) {
        return vo(findById(id));
    }
}
